﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using Microsoft.Practices.Unity;
using Sern.Abstracts.Tracker.DataContracts;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Common;
using Sern.ServiceImplementation.TrackerDefinition.Data;

namespace Sern.ServiceImplementation.TrackerDefinition.Service
{
    public class LocalRegistrar : IComponentRegistrar
    {
        [ThreadStatic] private static TrackerEntityContainer TrackerEntityContainer;

        public void Register(IUnityContainer container)
        {
            //TODO: We need to allow the connection string to be passed in here.
            container.RegisterType<TrackerEntityContainer>(
                    new InjectionFactory(c =>   TrackerEntityContainer ?? 
                        (TrackerEntityContainer = 
                            !string.IsNullOrWhiteSpace(TrackerSettings.Default.TrackerConnectionString)?
                                new TrackerEntityContainer(TrackerSettings.Default.TrackerConnectionString) : 
                                new TrackerEntityContainer()
                         )
                    )
                );

            //container.RegisterType()
            container.RegisterType<IRepository<Client>, EFRepository<TrackerEntityContainer, Client>>();
            container.RegisterType<IRepository<Job>, EFRepository<TrackerEntityContainer, Job>>();
            container.RegisterType<IRepository<KeyTree>, EFRepository<TrackerEntityContainer, KeyTree>>();
            container.RegisterType<IRepository<KeyAtClientLog>, EFRepository<TrackerEntityContainer, KeyAtClientLog>>();

            container.RegisterType<IEnumerable<IClient<ITrackerMonitoringClient>>>(
                new InjectionFactory(c =>
                                     c.Resolve<IRepository<Client>>()
                                         .Records
                                         .OfType<ClientStatusInfo>()
                                         .Where(_ => _.Type == (int) ClientType.TrackerMonitor)
                                         .Select(_ => _.Uri)
                                         .ToArray()
                                         .Select(_ => new ChannelFactory<ITrackerMonitoringClient>(
                                                          c.Resolve<IBindingFactory>()[ClientType.TrackerMonitor]().Binding,
                                                          _).Wrap()
                                                )
                                        )
            );
        }
    }
}
